<template>
  <div class="custom-properties-panel">
    <div class="empty" v-if="selectedElements.length <= 0">请选择一个元素</div>
    <div class="empty" v-else-if="selectedElements.length > 1">只能选择一个元素</div>
    <div v-else>
      <fieldset class="element-item">
        <label>id</label>
        <span>{{ element.id }}</span>
      </fieldset>
      <fieldset class="element-item">
        <label>name</label>
        <input :value="element.name" @change="changeField('name',$event)" />
      </fieldset>
      <fieldset class="element-item">
        <label>customProps</label>
        <input :value="element.customProps" @change="changeField('customProps',$event)" />
      </fieldset>
      <fieldset class="element-item">
        <label>节点颜色</label>
        <input type="color" :value="element.color" @change="changeField('color',$event)" />
      </fieldset>
      <fieldset class="element-item" v-if="isEvent">
        <label>修改event节点类型</label>
        <select @change="changeEventType($event)" :value="eventType">
          <option v-for="option in eventTypes" :key="option.value" :value="option.value">{{ option.label }}</option>
        </select>
      </fieldset>
      <fieldset class="element-item" v-if="isTask">
        <label>修改Task节点类型</label>
        <select @change="changeTaskType" :value="taskType">
          <option v-for="option in taskTypes" :key="option.value" :value="option.value">{{ option.label }}</option>
        </select>
      </fieldset>
    </div>
  </div>
</template>

<script>
import { reactive, toRefs, computed, onMounted } from 'vue'
export default {
  name: 'PropertiesView',
  props: {
    modeler: {
      type: Object,
      default: () => ({})
    }
  },
  setup (props) {
    const state = reactive({
      bpmnModeler: props.modeler,
      selectedElements: [],
      element: null,
      eventTypes: [
        { label: '默认', value: '' },
        { label: 'MessageEventDefinition', value: 'bpmn:MessageEventDefinition' },
        { label: 'TimerEventDefinition', value: 'bpmn:TimerEventDefinition' },
        { label: 'ConditionalEventDefinition', value: 'bpmn:ConditionalEventDefinition' }
      ],
      eventType: '',
      taskTypes: [
        { label: 'Task', value: 'bpmn:Task' },
        { label: 'ServiceTask', value: 'bpmn:ServiceTask' },
        { label: 'SendTask', value: 'bpmn:SendTask' },
        { label: 'UserTask', value: 'bpmn:UserTask' }
      ],
      taskType: ''
    })

    onMounted(() => {
      init()
    })

    const init = () => {
      state.bpmnModeler.on('selection.changed', e => {
        state.selectedElements = e.newSelection
        state.element = e.newSelection[0]
        setDefaultProperties()
      })
      state.bpmnModeler.on('element.changed', e => {
        const { element } = e
        const currentElement = state.element
        if (!currentElement) {
          return
        }
        // update panel, if currently selected element changed
        if (element.id === currentElement.id) {
          state.element = element
        }
      })
    }

    const setDefaultProperties = () => {
      if (state.element) {
        const { type, businessObject } = state.element
        const { name, $attrs } = businessObject
        state.element.customProps = $attrs.customProps
        state.element.color = $attrs.color
        if (verifyIsEvent(type)) {
          state.eventType = businessObject.eventDefinitions ? businessObject.eventDefinitions[0].$type : ''
        } else if (verifyIsTask(type)) {
          state.taskType = type
        }
        state.element.name = name
      }
    }

    // const reverseColor = (OldColorValue) => {
    //   const oldColorValue = '0x' + OldColorValue.replace(/#/g, '')
    //   const str = '000000' + (0xFFFFFF - oldColorValue).toString(16)
    //   const newColor = '#' + str.substring(str.length - 6, str.length)
    //   return newColor
    // }

    const verifyIsEvent = (type) => {
      return type.includes('Event')
    }

    const verifyIsTask = (type) => {
      return type.includes('Task')
    }

    /**
     * 改变控件触发的事件
     * @param { Object } input的Event
     * @param { String } 要修改的属性的名称
     */
    const changeField = (type, event) => {
      const value = event.target.value
      state.element[type] = value
      const properties = {}
      properties[type] = value
      if (type === 'color') {
        onChangeColor(value)
      }
      updateProperties(properties)
    }
    const onChangeColor = (color) => {
      const modeling = state.bpmnModeler.get('modeling')
      const elementRegistry = state.bpmnModeler.get('elementRegistry')
      const shap = elementRegistry.get(state.element.id)
      modeling.setColor([shap], {
      //  fill: color,
        stroke: color,
        opacity: 0.4
      })
    }

    const changeEventType = (event) => {
      const value = event.target.value
      const bpmnReplace = state.bpmnModeler.get('bpmnReplace')
      state.eventType = value
      const elementRegistry = state.bpmnModeler.get('elementRegistry')
      const shape = elementRegistry.get(state.element.id)
      bpmnReplace.replaceElement(shape, {
        type: state.element.businessObject.$type,
        eventDefinitionType: value
      })
    }

    const changeTaskType = (event) => {
      const value = event.target.value
      const bpmnReplace = state.bpmnModeler.get('bpmnReplace')
      const elementRegistry = state.bpmnModeler.get('elementRegistry')
      const shape = elementRegistry.get(state.element.id)
      bpmnReplace.replaceElement(shape, {
        type: value
      })
    }

    /**
     * 更新元素属性
     * @param { Object } 要更新的属性, 例如 { name: '' }
     */
    const updateProperties = (properties) => {
      const modeling = state.bpmnModeler.get('modeling')
      const elementRegistry = state.bpmnModeler.get('elementRegistry')
      const startEvent = elementRegistry.get(state.element.id)
      modeling.updateProperties(startEvent, properties)
    }

    const isEvent = computed(() => {
      return verifyIsEvent(state.element.type)
    })

    const isTask = computed(() => {
      return verifyIsTask(state.element.type)
    })

    return {
      ...toRefs(state),
      isEvent,
      isTask,
      changeField,
      changeEventType,
      changeTaskType
    }
  }
}
</script>

<style scoped>
.custom-properties-panel {
  position: absolute;
  right: 0;
  top: 0;
  width: 300px;
  background-color: #fff9f9;
  border-color: rgba(0, 0, 0, 0.09);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
  padding: 20px;
}
.empty {
  height: 200px;
  line-height: 200px;
  font-weight: 700;
}
.element-item {
  padding: 10px;
  margin-top: 5px;
  border: 1px solid;
  border-color: darkorange;
  border-radius: 8px;
}
.element-item:first-child {
  margin-top: 0;
}
.custom-properties-panel input,
.custom-properties-panel textarea {
  padding: 4px 11px;
  color: rgba(0, 0, 0, 0.65);
  font-size: 14px;
  background-color: #fff;
  background-image: none;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  transition: all 0.3s;
  outline: none;
}
.custom-properties-panel input:focus,
.custom-properties-panel button:focus,
.custom-properties-panel textarea:focus,
.custom-properties-panel [contenteditable]:focus {
  border-color: rgb(239, 112, 96);
  box-shadow: 0 0 1px 2px rgba(239, 112,  96, 0.2);
}
.custom-properties-panel label {
  font-weight: bold;
}

.custom-properties-panel label:after {
  content: ': ';
}

.custom-properties-panel button + button {
  margin-left: 10px;
}
</style>
